package cn.gailvlun.gll.presentation.emotion.core

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
import android.animation.PropertyValuesHolder
import android.app.Activity
import android.content.Intent
import android.databinding.DataBindingUtil
import android.databinding.ObservableField
import android.graphics.drawable.BitmapDrawable
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.widget.CheckedTextView
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import cn.gailvlun.gll.R
import cn.gailvlun.gll.databinding.PopupFunctionBinding
import cn.gailvlun.gll.mgr.UploadMgr
import cn.gailvlun.gll.net.HttpMethods
import cn.gailvlun.gll.net.HttpSubscriber
import cn.gailvlun.gll.net.NullSubscriber
import cn.gailvlun.gll.net.base.Profile
import cn.gailvlun.gll.net.emotion.*
import cn.gailvlun.gll.presentation.base.BaseActivity
import cn.gailvlun.gll.presentation.core.ObservableViewModel
import cn.gailvlun.gll.presentation.emotion.EmotionDetail2Activity
import cn.gailvlun.gll.presentation.emotion.EmotionSameListActivity
import cn.gailvlun.gll.presentation.emotion.bean.EmotionDetailTransfer
import cn.gailvlun.gll.presentation.profile.OtherProfileActivity
import cn.gailvlun.gll.presentation.profile.ProfileActivity
import cn.gailvlun.gll.util.*
import com.afollestad.materialdialogs.MaterialDialog
import com.alibaba.sdk.android.oss.ClientException
import com.alibaba.sdk.android.oss.ServiceException
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback
import com.alibaba.sdk.android.oss.model.PutObjectRequest
import com.alibaba.sdk.android.oss.model.PutObjectResult
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.ScreenUtils
import com.luck.picture.lib.PictureSelector
import com.luck.picture.lib.PictureSelectorActivity
import com.luck.picture.lib.config.PictureConfig
import com.luck.picture.lib.config.PictureMimeType
import io.reactivex.functions.Consumer
import org.joda.time.DateTime
import rx_activity_result2.Result
import rx_activity_result2.RxActivityResult


const val RESULT_DELETE = 100

open class BaseViewModel : ObservableViewModel {

    private var mAdapter: BaseAdapter<Any>?
    open var mActivity: BaseActivity
    var coverUri: ObservableField<String> = ObservableField("")
    private lateinit var mContentView: View
    private lateinit var mPopup: PopupWindow


    protected lateinit var mSuperUserPopup: PopupWindow
    protected lateinit var mUserPopup: PopupWindow
    protected lateinit var mOperationsPopup: PopupWindow
    protected lateinit var mOthersPopup: PopupWindow


    protected lateinit var mCausePopup: PopupWindow
    protected val layoutInflater: LayoutInflater

    var functionPopupWindow: PopupWindow? = null
    protected lateinit var functionViewBinding: PopupFunctionBinding

    var theItem: Emotion? = null
    var emotionId: Int? = null
    private lateinit var mParentView: View

    companion object {

        var PREF_COVER_URI = "cover_uri"
    }

    constructor(activity: BaseActivity, adapter: BaseAdapter<Any>?) : super() {
        mActivity = activity
        mAdapter = adapter

        layoutInflater = LayoutInflater.from(mActivity)

    }


    fun baseJump2Profile(whichProfile: Profile) {
        val myId = ProfileUtil.getUserId()
        if (myId != null && whichProfile.id == myId) {
            ProfileActivity.openActivity(mActivity)
        } else {
            OtherProfileActivity.openActivity(mActivity, whichProfile)
        }
    }

    fun baseEmotionHeart(view: View, emotion: Emotion) {

        var ctvLike = view as CheckedTextView


















        var animScaleX = PropertyValuesHolder.ofFloat("scaleX", 1f, 1.2f, 1f)
        var animScaleY = PropertyValuesHolder.ofFloat("scaleY", 1f, 1.2f, 1f)
        var anim = ObjectAnimator.ofPropertyValuesHolder(view, animScaleX, animScaleY).setDuration(600L)
        anim.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator?) {
                super.onAnimationEnd(animation)
                functionPopupWindow?.dismiss()
            }

            override fun onAnimationStart(animation: Animator?) {
                super.onAnimationStart(animation)

                heart(emotion)
            }

        })

        anim.start()

    }

    fun heart(emotion: Emotion) {
        val req = EmotionHeartReq(emotion.id, if (emotion.heart.isHearted) -1 else 1)
        HttpMethods.getEmotionService()
                .emotionHeart(req)
                .compose(RxUtil.applyScheduler())
                .subscribe(object : HttpSubscriber<Emotion>() {
                    override fun onSuccess(response: Emotion) {
                        emotion.heart.isHearted = response.heart.isHearted
                        emotion.heart.heartObservable.set(response.heart.isHearted)
                        
                        emotion.heart.countObservable.set(response.heart.count)
                        if (emotion.heart.isHearted) {
                            emotion.readObservable.set(emotion.read_num + 1)
                        }
                        heartEmotionCallback(response.heart)
                    }

                    override fun onFailure(errMsg: String?, response: Emotion?, code: Int) {

                    }
                })
    }

    open fun heartEmotionCallback(heart: Heart) {

    }


    var oldEmotion: Emotion? = null
    fun baseShowFunction(anchor: View, emotion: Emotion) {
        functionViewBinding.emotion = emotion


        if (oldEmotion != null && emotion.id != oldEmotion?.id) {
            functionPopupWindow?.dismiss()
            functionPopupWindow?.showAsDropDown(anchor, -DensityUtil.dp2px(mActivity, 156f), -(anchor.height / 2 + DensityUtil.dp2px(mActivity, 22f)))

        } else if (oldEmotion == null) {
            oldEmotion = emotion
            functionPopupWindow?.showAsDropDown(anchor, -DensityUtil.dp2px(mActivity, 156f), -(anchor.height / 2 + DensityUtil.dp2px(mActivity, 22f)))

        } else if (oldEmotion?.id == emotion.id) {

            if (functionPopupWindow?.isShowing!!) {
                functionPopupWindow?.dismiss()

            } else {
                functionPopupWindow?.showAsDropDown(anchor, -DensityUtil.dp2px(mActivity, 156f), -(anchor.height / 2 + DensityUtil.dp2px(mActivity, 22f)))
            }

        }
    }


    fun baseToEmotionDetail(emotion: Emotion) {
        val transfer = EmotionDetailTransfer()
        transfer.id = emotion.id
        val userId = ProfileUtil.getUserId()
        if (userId != null && emotion.owner.id == userId) {
            transfer.title = R.string.emotion_my_emotion
        }
        EmotionDetail2Activity.openActivity(mActivity, transfer, object : Consumer<Result<BaseActivity>> {
            override fun accept(t: Result<BaseActivity>?) {
                if (RESULT_DELETE == t?.resultCode()) {

                    deleteEmotionCallback(emotion)
                }
            }
        })
    }

    fun baseJump2EmotionSame(emotion: Emotion) {
        EmotionSameListActivity.openActivity(mActivity, emotion.emotionTagList[0].id)
    }

    fun initPopWindow(parentView: View) {
        mParentView = parentView
        
        functionViewBinding = DataBindingUtil.inflate(layoutInflater, R.layout.popup_function, null, false)
        functionViewBinding.presenter = this

        functionPopupWindow = PopupWindow(functionViewBinding.root, DensityUtil.dp2px(mActivity, 156f), DensityUtil.dp2px(mActivity, 40f), false)
        functionPopupWindow?.animationStyle = R.style.popupwindow_anim_style
        functionPopupWindow?.setBackgroundDrawable(BitmapDrawable())

        
        mContentView = layoutInflater.inflate(R.layout.popup_replace_background, null, false)
        mPopup = PopupWindow(mContentView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
        mContentView.findViewById<TextView>(R.id.tv_open_album).setOnClickListener { _ ->
            openAlum()
        }
        mContentView.findViewById<TextView>(R.id.tv_cancel).setOnClickListener { _ ->
            mPopup.dismiss()
        }

        
        
        val causeView = layoutInflater.inflate(R.layout.popup_report_cause, null, false)
        mCausePopup = PopupWindow(causeView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)

        causeView.findViewById<TextView>(R.id.tv_cause_ad).setOnClickListener { _ ->
            val req = ReportReq()
            req.targetType = "EmotionRecord"
            req.reasonType = "ad"
            req.targetId = theItem?.id!!

            reportEmotion(req)

        }

        causeView.findViewById<TextView>(R.id.tv_cause_others).setOnClickListener { _ ->
            val req = ReportReq()
            req.targetType = "EmotionRecord"
            req.reasonType = "others"
            req.targetId = theItem?.id!!
            reportEmotion(req)
        }

        causeView.findViewById<TextView>(R.id.tv_cancel).setOnClickListener { _ ->
            mCausePopup.dismiss()
        }

        

        
        val superUserView = layoutInflater.inflate(R.layout.popup_super_user, null, false)
        mSuperUserPopup = PopupWindow(superUserView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
        superUserView.findViewById<TextView>(R.id.tv_delete).setOnClickListener { _ ->
            mSuperUserPopup.dismiss()
            deleteEmotion()

        }
        superUserView.findViewById<TextView>(R.id.tv_shield).setOnClickListener { _ ->
            mSuperUserPopup.dismiss()
            shieldEmotion()
        }
        superUserView.findViewById<TextView>(R.id.tv_cancel).setOnClickListener { _ ->
            mSuperUserPopup.dismiss()
        }


        
        val userView = layoutInflater.inflate(R.layout.popup_user, null, false)
        mUserPopup = PopupWindow(userView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
        userView.findViewById<TextView>(R.id.tv_delete).setOnClickListener { _ ->
            mUserPopup.dismiss()
            deleteEmotion()

        }

        userView.findViewById<TextView>(R.id.tv_cancel).setOnClickListener { _ ->
            mUserPopup.dismiss()
        }


        
        val operationsView = layoutInflater.inflate(R.layout.popup_operations, null, false)
        mOperationsPopup = PopupWindow(operationsView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
        operationsView.findViewById<TextView>(R.id.tv_report).setOnClickListener { _ ->
            mOperationsPopup.dismiss()
            mCausePopup.isOutsideTouchable = true
            mCausePopup.setBackgroundDrawable(BitmapDrawable())
            mCausePopup.showAtLocation(operationsView, Gravity.BOTTOM, 0, 0)


        }

        operationsView.findViewById<TextView>(R.id.tv_shield).setOnClickListener { _ ->
            mOperationsPopup.dismiss()

            shieldEmotion()
        }

        operationsView.findViewById<TextView>(R.id.tv_cancel).setOnClickListener { _ ->
            mOperationsPopup.dismiss()
        }

        

        val othersView = layoutInflater.inflate(R.layout.popup_others, null, false)
        mOthersPopup = PopupWindow(othersView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)

        othersView.findViewById<TextView>(R.id.tv_report).setOnClickListener { _ ->
            mOthersPopup.dismiss()

            mCausePopup.isOutsideTouchable = true
            mCausePopup.setBackgroundDrawable(BitmapDrawable())
            mCausePopup.showAtLocation(othersView, Gravity.BOTTOM, 0, 0)
        }
        othersView.findViewById<TextView>(R.id.tv_cancel).setOnClickListener { _ ->
            mOthersPopup.dismiss()
        }

    }

    private fun reportEmotion(req: ReportReq) {
        val pd = DialogUtil.showIndeterminate(mActivity)
        HttpMethods.getEmotionService()
                .report(req)
                .compose(RxUtil.applyScheduler())
                .compose(mActivity.bindToLifecycle())
                .subscribe(object : HttpSubscriber<ReportRes>() {
                    override fun onSuccess(response: ReportRes?) {
                        pd.dismiss()
                        mCausePopup.dismiss()
                        functionPopupWindow?.dismiss()
                        ToastUtil.showShort("举报成功")
                    }

                    override fun onFailure(errMsg: String?, response: ReportRes?, code: Int) {
                        pd.dismiss()
                        DialogUtil.showError(mActivity, errMsg)
                    }
                })
    }


    private fun deleteEmotion() {
        if (emotionId != null) {
            MaterialDialog.Builder(mActivity)
                    .title("确定删除这条情绪吗？")
                    .positiveText("确定")
                    .onPositive { dialog, _ ->
                        dialog.dismiss()
                        val pd = DialogUtil.showIndeterminate(mActivity)
                        
                        HttpMethods.getEmotionService()
                                .deleteEmotion(emotionId!!, (DateTime.now().withTimeAtStartOfDay().millis / 1000).toInt())
                                .compose(RxUtil.applyNullScheduler())
                                .subscribe(object : NullSubscriber() {
                                    override fun onSuccess() {

                                        mAdapter?.remove(theItem)
                                        pd.dismiss()
                                        ToastUtil.showShort("删除成功")
                                        deleteEmotionCallback(theItem!!)
                                        functionPopupWindow?.dismiss()
                                    }

                                    override fun onFailure(errMsg: String?, code: Int) {
                                        pd.dismiss()
                                        DialogUtil.showError(mActivity, errMsg)
                                    }
                                })
                    }
                    .negativeText("取消")
                    .onNegative { dialog, _ ->
                        dialog.dismiss()
                    }.show()
        }

    }

    open fun deleteEmotionCallback(theItem: Emotion) {

    }


    private fun shieldEmotion() {
        val pd = DialogUtil.showIndeterminate(mActivity)
        HttpMethods.getEmotionService()
                .shieldEmotion(RecordId(emotionId))
                .compose(RxUtil.applyNullScheduler())
                .subscribe(
                        object : NullSubscriber() {
                            override fun onFailure(errMsg: String?, code: Int) {
                                pd.dismiss()
                                DialogUtil.showError(mActivity, errMsg)
                            }

                            override fun onSuccess() {
                                mAdapter?.remove(theItem as Emotion)
                                pd.dismiss()
                                functionPopupWindow?.dismiss()
                                ToastUtil.showShort("折叠成功")
                            }
                        }
                )

    }

    
    fun baseShowReplaceBgFun(parentView: View) {
        mPopup.isOutsideTouchable = true
        mPopup.setBackgroundDrawable(BitmapDrawable())
        mPopup.showAtLocation(parentView, Gravity.BOTTOM, 0, 0)
    }

    fun baseShowOperateEmotionWindow(parentView: View, emotion: Emotion) {

        theItem = emotion
        this.emotionId = emotion.id
        val whichId = emotion.owner.id
        val myId = ProfileUtil.getProfile().id
        
        val privileged = SPUtil.getBoolean(SPUtil.USER, "emo_privileged")

        if (whichId == myId && privileged) {
            mSuperUserPopup.isOutsideTouchable = true
            mSuperUserPopup.setBackgroundDrawable(BitmapDrawable())
            mSuperUserPopup.showAtLocation(mParentView, Gravity.BOTTOM, 0, 0)

        } else if (whichId == myId && !privileged) { 
            mUserPopup.isOutsideTouchable = true
            mUserPopup.setBackgroundDrawable(BitmapDrawable())
            mUserPopup.showAtLocation(mParentView, Gravity.BOTTOM, 0, 0)
        } else if (whichId != myId && privileged) {
            mOperationsPopup.isOutsideTouchable = true
            mOperationsPopup.setBackgroundDrawable(BitmapDrawable())
            mOperationsPopup.showAtLocation(mParentView, Gravity.BOTTOM, 0, 0)
        } else if (whichId != myId && !privileged) { 
            mOthersPopup.isOutsideTouchable = true
            mOthersPopup.setBackgroundDrawable(BitmapDrawable())
            mOthersPopup.showAtLocation(mParentView, Gravity.BOTTOM, 0, 0)

        }

    }


    private fun openAlum() {
        val screenWidth = ScreenUtils.getScreenWidth()
        PictureSelector.create(mActivity)
                .openGallery(PictureMimeType.ofImage())
                .maxSelectNum(1)
                .minSelectNum(1)
                .imageSpanCount(4)
                .selectionMode(PictureConfig.MULTIPLE)
                .previewImage(true)
                .isCamera(true)
                .imageFormat(PictureMimeType.PNG)
                .isZoomAnim(true)
                .sizeMultiplier(0.5f)
                .setOutputCameraPath("/camera")
                .previewEggs(true)
                .compress(true)
                .cropCompressQuality(80)
                .minimumCompressSize(200)
                .enableCrop(true)
                .circleDimmedLayer(false)
                .showCropFrame(true)


                

                .withAspectRatio(1, 1)
                .scaleEnabled(true)


        RxActivityResult.on(mActivity)
                .startIntent(Intent(mActivity, PictureSelectorActivity::class.java))
                .subscribe { activityResult ->
                    mPopup.dismiss()
                    if (activityResult.resultCode() == Activity.RESULT_OK) {
                        val data = PictureSelector.obtainMultipleResult(activityResult.data())
                        val path = if (data[0].isCompressed) {
                            data[0].compressPath
                        } else {
                            data[0].path
                        }

                        val pd = DialogUtil.showIndeterminate(mActivity)
                        UploadMgr.getInstance().upload(FileUtils.getFileName(path), path, object : OSSCompletedCallback<PutObjectRequest, PutObjectResult> {
                            override fun onFailure(request: PutObjectRequest?, clientException: ClientException?, serviceException: ServiceException?) {
                                pd.dismiss()
                                ToastUtil.showShort("图片上次失败，请重试")
                            }

                            override fun onSuccess(request: PutObjectRequest?, result: PutObjectResult?) {
                                HttpMethods.getEmotionService()
                                        .postCover(PostCover(request?.objectKey!!))
                                        .compose(RxUtil.applyNullScheduler())
                                        .subscribe(object : NullSubscriber() {
                                            override fun onSuccess() {
                                                pd.dismiss()
                                                coverUri.set(path)
                                                SPUtil.put(SPUtil.USER, PREF_COVER_URI, path)
                                                ToastUtil.showShort("背景图设置成功")
                                            }

                                            override fun onFailure(errMsg: String?, code: Int) {
                                                pd.dismiss()
                                                DialogUtil.showError(mActivity, errMsg)
                                            }
                                        })


                            }

                        }
                        )
                    }
                }
    }
}
